#!/usr/bin/env node

/**
 * AIDE 数据库初始化脚本 - Ubuntu版本
 * 支持Unix socket认证和密码认证
 */

const { Pool } = require('pg')
const fs = require('fs')
const path = require('path')
const { spawn } = require('child_process')

// 获取数据库配置
const getDatabaseConfig = () => {
  // 如果有DATABASE_URL，优先使用
  if (process.env.DATABASE_URL) {
    return {
      connectionString: process.env.DATABASE_URL,
      ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
    }
  }
  
  // Ubuntu默认配置：尝试Unix socket认证
  return {
    host: process.env.DB_HOST || '/var/run/postgresql', // Unix socket
    port: parseInt(process.env.DB_PORT || '5432'),
    database: process.env.DB_NAME || 'aide_db',
    user: process.env.DB_USER || 'postgres',
    password: process.env.DB_PASSWORD, // 可能为空，使用Unix socket
  }
}

// 尝试使用psql命令创建数据库
async function createDatabaseWithPsql(dbName) {
  return new Promise((resolve, reject) => {
    console.log('🔧 尝试使用 psql 命令创建数据库...')
    
    const psql = spawn('sudo', ['-u', 'postgres', 'psql', '-c', `CREATE DATABASE "${dbName}";`], {
      stdio: 'pipe'
    })
    
    let output = ''
    let error = ''
    
    psql.stdout.on('data', (data) => {
      output += data.toString()
    })
    
    psql.stderr.on('data', (data) => {
      error += data.toString()
    })
    
    psql.on('close', (code) => {
      if (code === 0 || error.includes('already exists')) {
        console.log(`✅ 数据库 "${dbName}" 准备就绪`)
        resolve(true)
      } else {
        console.log('❌ psql 命令失败:', error)
        resolve(false)
      }
    })
    
    psql.on('error', (err) => {
      console.log('❌ 无法执行 psql 命令:', err.message)
      resolve(false)
    })
  })
}

// 创建数据库
async function createDatabase() {
  const config = getDatabaseConfig()
  const targetDatabase = config.database || 'aide_db'
  
  // 方法1: 尝试使用psql命令
  const psqlSuccess = await createDatabaseWithPsql(targetDatabase)
  if (psqlSuccess) {
    return true
  }
  
  // 方法2: 尝试Node.js连接
  console.log('🔄 尝试使用Node.js连接...')
  
  const adminConfig = {
    ...config,
    database: 'postgres' // 连接到默认数据库
  }
  
  const pool = new Pool(adminConfig)
  
  try {
    const client = await pool.connect()
    
    // 检查数据库是否存在
    const result = await client.query(
      'SELECT 1 FROM pg_database WHERE datname = $1',
      [targetDatabase]
    )
    
    if (result.rows.length > 0) {
      console.log(`✅ 数据库 "${targetDatabase}" 已存在`)
      client.release()
      return true
    }
    
    // 创建数据库
    console.log(`🔧 创建数据库 "${targetDatabase}"...`)
    await client.query(`CREATE DATABASE "${targetDatabase}"`)
    console.log(`✅ 数据库 "${targetDatabase}" 创建成功`)
    
    client.release()
    return true
    
  } catch (error) {
    console.error('❌ Node.js连接失败:', error.message)
    return false
  } finally {
    await pool.end()
  }
}

async function initializeDatabase() {
  try {
    console.log('🚀 开始初始化 AIDE 数据库...')
    console.log('🐧 Ubuntu环境检测')
    
    // 显示当前配置
    const config = getDatabaseConfig()
    console.log('📋 数据库配置:')
    console.log(`   Host: ${config.host || config.connectionString}`)
    console.log(`   Database: ${config.database}`)
    console.log(`   User: ${config.user}`)
    
    // 首先确保数据库存在
    console.log('1️⃣ 检查并创建数据库...')
    const dbCreated = await createDatabase()
    if (!dbCreated) {
      throw new Error('数据库创建失败，请手动创建数据库或检查权限')
    }
    
    // 连接到目标数据库
    const pool = new Pool(getDatabaseConfig())
    const client = await pool.connect()
    console.log('✅ 数据库连接成功')
    
    // 读取初始化SQL文件
    const sqlPath = path.join(__dirname, 'src', 'database', 'init.sql')
    if (!fs.existsSync(sqlPath)) {
      throw new Error(`初始化SQL文件不存在: ${sqlPath}`)
    }
    
    const initSQL = fs.readFileSync(sqlPath, 'utf8')
    console.log('📖 读取初始化SQL脚本成功')
    
    // 执行初始化SQL
    console.log('🔧 执行数据库初始化...')
    await client.query(initSQL)
    console.log('✅ 数据库表结构创建成功')
    
    // 检查表是否创建成功
    const tablesResult = await client.query(`
      SELECT table_name 
      FROM information_schema.tables 
      WHERE table_schema = 'public' 
      ORDER BY table_name;
    `)
    
    const tables = tablesResult.rows.map(row => row.table_name)
    console.log('📋 已创建的表:')
    tables.forEach(table => {
      console.log(`   - ${table}`)
    })
    
    // 检查版本信息
    const versionResult = await client.query('SELECT version, applied_at FROM schema_versions ORDER BY applied_at DESC LIMIT 1')
    if (versionResult.rows.length > 0) {
      const { version, applied_at } = versionResult.rows[0]
      console.log(`📌 数据库版本: ${version} (${applied_at.toISOString()})`)
    }
    
    client.release()
    await pool.end()
    console.log('🎉 数据库初始化完成!')
    
  } catch (error) {
    console.error('❌ 数据库初始化失败:', error.message)
    
    if (error.code === 'ECONNREFUSED') {
      console.error('💡 建议检查:')
      console.error('   1. sudo systemctl status postgresql')
      console.error('   2. sudo systemctl start postgresql')
    } else if (error.code === '28P01') {
      console.error('💡 认证失败解决方案:')
      console.error('   1. sudo -u postgres psql')
      console.error('   2. \\password postgres')
      console.error('   3. 设置密码后重试')
    }
    
    process.exit(1)
  }
}

// 如果直接运行此脚本
if (require.main === module) {
  // 检查是否在Ubuntu环境
  console.log('🔍 环境检测...')
  
  if (!process.env.DATABASE_URL && !process.env.DB_PASSWORD) {
    console.log('⚠️  未检测到数据库密码配置')
    console.log('💡 Ubuntu PostgreSQL 认证选项:')
    console.log('')
    console.log('方法1: 设置postgres用户密码')
    console.log('   sudo -u postgres psql')
    console.log('   \\password postgres')
    console.log('   然后设置: export DB_PASSWORD="your_password"')
    console.log('')
    console.log('方法2: 使用DATABASE_URL')
    console.log('   export DATABASE_URL="postgresql://user:password@localhost:5432/aide_db"')
    console.log('')
    console.log('方法3: 创建专用用户')
    console.log('   sudo -u postgres createuser --interactive aide_user')
    console.log('   sudo -u postgres psql -c "ALTER USER aide_user PASSWORD \'password\';"')
    console.log('')
    console.log('🚀 尝试继续使用Unix socket认证...')
  }
  
  initializeDatabase()
}

module.exports = { initializeDatabase }
